﻿using System;
using System.Collections.Generic;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.GamePlay;

namespace IQIGame.Onigao.Logic
{
    public static class BuffController
    {
        public static BuffHandler Add(this BuffComponent rMaker, BuffComponent rTarget, int nBuffID, int nStack = 1, int param = 0)
        {
            var rBuffConfig = TableCenter.buff.Get(nBuffID);
            if (rBuffConfig == null)
            {
                return null;
            }

            BuffHandler rBuff = null;

            var rAddType = (EBuffAddType)rBuffConfig.AddType;
            if (rAddType == EBuffAddType.Exclusive || rAddType == EBuffAddType.Replace)
            {
                BuffHandler rOldBuff = null;
                for (int i = 0; i < rTarget.buffList.Count; i++)
                {
                    var rHandler = rTarget.buffList[i];
                    if (rHandler.config.Type == rBuffConfig.Type)
                    {
                        rOldBuff = rHandler;
                    }
                }
                if (rOldBuff != null)
                {
                    if ((rOldBuff.config.TypePriiority == rBuffConfig.TypePriiority && rAddType == EBuffAddType.Replace) ||
                        rOldBuff.config.TypePriiority > rBuffConfig.TypePriiority)
                    {
                        rTarget.Destroy(rOldBuff);
                    }
                    else
                    {
                        return null;
                    }
                }
            }

            for (int i = 0; i < rTarget.buffList.Count; i++)
            {
                var rHandler = rTarget.buffList[i];
                if (rHandler.config.Id == rBuffConfig.Id)
                {
                    rBuff = rHandler;
                }
            }

            bool bIsNew = rBuff == null;
            if (bIsNew)
            {
                rBuff = BuffFactory.CreateBuff(rMaker, rTarget, nBuffID);
                if (rBuff == null)
                {
                    return null;
                }
            }

            rTarget.unit.battle.playCtrl.triggerCtrl.Broadcast(EBattleTriggerType.Battle_AddBuff, rBuff);

            if (bIsNew)
            {
                rBuff.target.buffList.Add(rBuff);
                rBuff.maker.makerBuffList.Add(rBuff);
                rBuff.OnEnable(nStack);
            }

            rBuff.AddStack(nStack, param);

            // pod在addstack后
            var rResultCtrl = rTarget.unit.battle.playCtrl.resultCtrl;
            var rPOD = BattleUpdateFactory.CreateBuffChange(rBuff, 0, rTarget.unit.GUID);
            rResultCtrl.Add(rPOD);

            // 瞬时buff
            if (rBuff.timeDuration == 0)
            {
                BuffController.Destroy(rBuff.target, rBuff);
            }
            return rBuff;
        }

        public static void Remove(this BuffComponent rTarget, int nBuffID, int nStack = 1)
        {
            var rBuff = rTarget.buffList.Find((x) => x.buffID == nBuffID);
            if (rBuff != null)
            {
                rTarget.Remove(rBuff, nStack);
            }
        }

        public static void Remove(this BuffComponent rTarget, BuffHandler rBuff, int nStack = 1)
        {
            if (rBuff != null && rBuff.RemoveStack(nStack))
            {
                var rResultCtrl = rTarget.unit.battle.playCtrl.resultCtrl;
                var rPOD = BattleUpdateFactory.CreateBuffChange(rBuff, 1, rTarget.unit.GUID);
                rResultCtrl.Add(rPOD);
                rTarget.unit.battle.playCtrl.triggerCtrl.Broadcast(EBattleTriggerType.Battle_RemoveBuff, rBuff.buffID);
            }
        }

        public static void Destroy(this BuffComponent rTarget, BuffHandler rHandler)
        {
            var nBuffID = rHandler.buffID;
            rHandler.OnDisable();
            rTarget.buffList.Remove(rHandler);
            rHandler.maker.makerBuffList.Remove(rHandler);

            var rResultCtrl = rTarget.unit.battle.playCtrl.resultCtrl;
            var rPOD = BattleUpdateFactory.CreateBuffChange(rHandler, 3, rTarget.unit.GUID);
            rResultCtrl.Add(rPOD);

            rTarget.unit.battle.playCtrl.triggerCtrl.Broadcast(EBattleTriggerType.Battle_DestroyBuff, nBuffID);
        }

        public static void ModifyBuffState(this BuffComponent rTarget, EBuffCustomState rState, bool bAdd = true)
        {
            rTarget.buffState.TryGetValue(rState, out var nCount);
            nCount = Math.Max(0, nCount + (bAdd ? 1 : -1));
            rTarget.buffState[rState] = nCount;

            var rCustom = rTarget.unit.GetComponent<CustomPropertyComponent>(ETComponentType.CustomPropertyComponent);
            switch (rState)
            {
                case EBuffCustomState.Ice:
                    rCustom.ModifyIntProperty(ECustomProperty.ForbidTurn, bAdd);
                    rCustom.ModifyIntProperty(ECustomProperty.ForbidTriggerSkill, bAdd);
                    break;
                case EBuffCustomState.Slince:
                    rCustom.ModifyIntProperty(ECustomProperty.ForbidTriggerSkill, bAdd);
                    break;
            }
            // 当前所有buff控制效果都可以打断蓄力
            if (bAdd && rCustom.GetProperty<bool>(ECustomProperty.Charge))
            {
                var rChargeComp = rTarget.unit.GetComponent<ChargeComponent>(ETComponentType.ChargeComponent);
                rChargeComp.ChargeStop();
            }
        }
    }
}